#[derive(FromForm)]
struct RegInfo {
    user: String,
    email: String,
    tel: String,
    alipay_user: String,
    alipay_name: String,
    qq_number: String,
    password: String
}

#[post("/reg", data = "<reg_info>")]
fn reg(reg_info: Form<RegInfo>, state: State<MySqlDriver>, cookies: Cookies) -> String {
    let mut except_vec: Vec<char> = Vec::new();
    except_vec.push('\'');
    except_vec.push('"');
    except_vec.push('\\');
    let user: HoString = HoString::copy_str(reg_info.user.as_str());
    let email: HoString = HoString::copy_str(reg_info.email.as_str());
    let tel: HoString = HoString::copy_str(reg_info.tel.as_str());
    let alipay_user: HoString = HoString::copy_str(reg_info.alipay_user.as_str());
    let alipay_name: HoString = HoString::copy_str(reg_info.alipay_name.as_str());
    let qq_number: HoString = HoString::copy_str(reg_info.qq_number.as_str());
    let password: HoString = HoString::copy_str(reg_info.password.as_str());
    if user.length() == 0 ||
        email.length() == 0 ||
        tel.length() == 0 ||
        alipay_user.length() == 0 ||
        alipay_name.length() == 0 ||
        qq_number.length() == 0 ||
        password.length() == 0 {
        return "fail:表单中存在空值".to_string();
    } else if user.length() > 15 || password.length() > 20 {
        return "fail:账号不能超过15个字符，密码不能超过20个字符".to_string();
    } else if user.contains_char_vec(except_vec.clone(), 0) == true ||
                email.contains_char_vec(except_vec.clone(), 0) == true ||
                tel.contains_char_vec(except_vec.clone(), 0) == true ||
                alipay_user.contains_char_vec(except_vec.clone(), 0) == true ||
                alipay_name.contains_char_vec(except_vec.clone(), 0) == true ||
                qq_number.contains_char_vec(except_vec.clone(), 0) == true ||
                password.contains_char_vec(except_vec.clone(), 0) == true {
        return "fail:表单值不能包含引号和斜杠".to_string();
    } else {
        let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
        let pool: Pool;
        if let Ok(p) = pool_result {
            pool = p;
        } else {
            return "fail:无法建立数据库连接".to_string();
        }
        let pool_conn: Result<PooledConn, mysql::Error> = pool.get_conn();
        let mut conn: PooledConn;
        if let Ok(pc) = pool_conn {
            conn = pc;
        } else {
            return "fail:无法获取数据库连接".to_string();
        }
        let mut sql: String = format!("SELECT COUNT(`id`) AS `id_count` \
            FROM `user` WHERE `account` = '{}' LIMIT 1", user.to_str());
        let result_rows: Result<Option<Row>, mysql::Error> = conn.query_first(sql);
        let row: Row;
        if let Ok(Some(r)) = result_rows {
            row = r;
        } else {
            return "fail:数据查询失败".to_string();
        }
        let mut id_count: usize = 0;
        let id_count_op: Option<usize> = row.get("id_count");
        if let Some(c) = id_count_op {
            id_count = c;
        }
        if id_count > 0 {
            return "fail:账号已存在".to_string();
        } else {
            let pwd_result: BcryptResult<String> = hash(password.to_str(), DEFAULT_COST);
            if let Ok(pwd) = pwd_result {
                sql = "INSERT INTO `user`(\
                    `account`, `password`, `email`, `tel`, `alipay_account`, \
                    `alipay_name`, `qq_number`, `push_id`, `commission`) VALUES (\
                    :user, :pwd, :email, :tel, :alipay_user, :alipay_name, \
                    :qq_number, :push_id, 0)".to_string();
                let push_id_op: Option<&Cookie> = cookies.get("push_id");
                let push_id_str: &str;
                if let Some(push_id_cookie) = push_id_op {
                    push_id_str = &push_id_cookie.value();
                } else {
                    push_id_str = "0";
                }
                let exec_result: Result<(), mysql::Error> = conn.exec_drop(sql, params!{
                    "user" => reg_info.user.clone(),
                    "pwd" => pwd.clone(),
                    "email" => reg_info.email.clone(),
                    "tel" => reg_info.tel.clone(),
                    "alipay_user" => reg_info.alipay_user.clone(),
                    "alipay_name" => reg_info.alipay_name.clone(),
                    "qq_number" => reg_info.qq_number.clone(),
                    "push_id" => push_id_str
                });
                if let Ok(_) = exec_result {
                    HoFile::write_file(format!("./ws/ws_session/{}.txt", conn.last_insert_id()).as_str(), "");
                    return "success:".to_string();
                } else {
                    return "fail:账户创建失败".to_string();
                }
            } else {
                return "fail:无法加密密码".to_string();
            }
        }
    }
}

#[get("/register")]
fn register(cookies: Cookies) -> Response<'static> {
    let mut login_str: HoString = HoFile::read_file_bytes("web/register.html");
    let push_id_op: Option<&Cookie> = cookies.get("push_id");
    let push_id_str: &str;
    if let Some(push_id_cookie) = push_id_op {
        push_id_str = &push_id_cookie.value();
    } else {
        push_id_str = "0";
    }
    login_str = login_str.replace_bytes("{push_id}".as_bytes(), push_id_str.as_bytes(), 1);
    let html: String = login_str.to_str().to_string().to_owned();
    let mut res = Response::new();
    res.set_header(ContentType::HTML);
    res.set_sized_body(Cursor::new(html));
    return res;
}
